package com.asiainfo.ai.admin.utils;

import cn.hutool.json.JSONUtil;
import com.asiainfo.ai.admin.constant.ApisConstant;
import com.asiainfo.ai.admin.constant.UcConstant;
import com.asiainfo.ai.admin.controller.vo.api.ApiUserRedisBean;
import com.asiainfo.ai.core.constants.RedisConstant;
import com.google.common.base.Strings;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.connection.StringRedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

@Slf4j
@Component
public class RedisUtils {

    private final StringRedisTemplate stringRedisTemplate;

    private final StringRedisTemplate testStringRedisTemplate;

    private final StringRedisTemplate productStringRedisTemplate;

    public RedisUtils(@Qualifier(ApisConstant.DEVELOP_STRING_REDIS_TEMPLATE) StringRedisTemplate stringRedisTemplate,
                         @Qualifier(ApisConstant.TEST_STRING_REDIS_TEMPLATE) StringRedisTemplate testStringRedisTemplate,
                         @Qualifier(ApisConstant.PRODUCTION_STRING_REDIS_TEMPLATE) StringRedisTemplate productStringRedisTemplate) {
        this.stringRedisTemplate = stringRedisTemplate;

        this.testStringRedisTemplate = testStringRedisTemplate;
        this.productStringRedisTemplate = productStringRedisTemplate;
    }

    public void deleteFromRedisAll() {
        Set<String> devKeys = stringRedisTemplate.keys(UcConstant.API_USER_KEY_PREFIX + "*");
        Set<String> productKeys = productStringRedisTemplate.keys(UcConstant.API_USER_KEY_PREFIX + "*");
        stringRedisTemplate.delete(devKeys);
        productStringRedisTemplate.delete(productKeys);
        try {
            Set<String> testKeys = testStringRedisTemplate.keys(UcConstant.API_USER_KEY_PREFIX + "*");
            testStringRedisTemplate.delete(testKeys);
        } catch (Exception e) {
            log.error("更新测试域redis出错", e);
        }
    }

    public void deleteFromRedis(String apiUserId) {
        String key = Strings.lenientFormat("%s%s%s", UcConstant.API_USER_KEY_PREFIX, apiUserId, "*");
        Set<String> devKeys = stringRedisTemplate.keys(key);
        Set<String> productKeys = productStringRedisTemplate.keys(key);
        stringRedisTemplate.delete(devKeys);
        productStringRedisTemplate.delete(productKeys);
        try {
            Set<String> testKeys = testStringRedisTemplate.keys(key);
            testStringRedisTemplate.delete(testKeys);
        } catch (Exception e) {
            log.error("更新测试域redis出错", e);
        }
    }


    public void writeToRedis(List<ApiUserRedisBean> apiUserRedisBeans, String profile) {
        if (RedisConstant.DEV.equals(profile)) {
            writeToRedis(apiUserRedisBeans, stringRedisTemplate, profile);
            return;
        }
        if (RedisConstant.TEST.equals(profile)) {
            writeToRedis(apiUserRedisBeans, testStringRedisTemplate, profile);
            return;
        }
        if (RedisConstant.PRODUCT.equals(profile)) {
            writeToRedis(apiUserRedisBeans, productStringRedisTemplate, profile);
        }
    }

    private void writeToRedis(List<ApiUserRedisBean> apiUserRedisBeans, StringRedisTemplate stringRedisTemplate, String profile) {
        stringRedisTemplate.executePipelined(
                (RedisCallback<Object>) connection -> {
                    StringRedisConnection stringRedisConn = (StringRedisConnection) connection;
                    for (ApiUserRedisBean apiUserRedisBean : apiUserRedisBeans) {
                        String apiUserId = apiUserRedisBean.getApiUserId();
                        String key = getApiUserCacheKey(apiUserId, profile);
                        stringRedisConn.set(key, JSONUtil.toJsonStr(apiUserRedisBean.getApiIdList()));
                    }
                    //必须返回null
                    return null;
                });
    }

    private static String getApiUserCacheKey(String apiUser, String profile) {
        return Strings.lenientFormat("%s%s:%s", UcConstant.API_USER_KEY_PREFIX, apiUser, profile);
    }

    public Map<String, StringRedisTemplate> getAllStringRedisTemplate() {
        HashMap<String, StringRedisTemplate> stringRedisTemplateMap = Maps.newHashMap();
        stringRedisTemplateMap.put(RedisConstant.DEV, stringRedisTemplate);
        stringRedisTemplateMap.put(RedisConstant.TEST, testStringRedisTemplate);
        stringRedisTemplateMap.put(RedisConstant.PRODUCT, productStringRedisTemplate);
        return stringRedisTemplateMap;
    }

}
